package com.aner.tester.generator;

import com.aner.tester.constant.Constant;
import com.aner.tester.object.ValueObject;
import com.aner.tester.scanner.FilterFlag;
import com.aner.tester.scanner.ScannerFactory;
import com.aner.tester.utils.text.StringUtils;

import java.lang.reflect.Array;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * data type manager
 *
 * @author aner
 * @version 1.0
 * @date 2020/12/12 8:33
 */
public class TypeManager {

    /**
     * Java basic type
     */
    public static Map<String, Class<?>> basicTypeMap = new HashMap<>();

    /**
     * custom type
     */
    public static Map<String, Class<?>> customTypeMap = new HashMap();

    /**
     * common collection type
     */
    public static Map<String, Class<?>> collectionTypeMap = new HashMap<>();

    /**
     * init
     *
     * @param packageNames
     */
    public static void init(String[] packageNames) {
        // basic and collection type init
        basicInit();
        // custom type init
        customObjectInit(packageNames);
    }

    private static void basicInit() {
        basicTypeMap.put(Constant.STRING, String.class);
        basicTypeMap.put(Constant.INTEGER, Integer.class);
        basicTypeMap.put(Constant.INT, Integer.class);
        basicTypeMap.put(Constant.DOUBLE_OBJECT, Double.class);
        basicTypeMap.put(Constant.DOUBLE, Double.class);
        basicTypeMap.put(Constant.LONG_OBJECT, Long.class);
        basicTypeMap.put(Constant.LONG, Long.class);
        basicTypeMap.put(Constant.FLOAT_OBJECT, Float.class);
        basicTypeMap.put(Constant.FLOAT, Float.class);
        basicTypeMap.put(Constant.DATE, Date.class);
        basicTypeMap.put(Constant.BOOLEAN_OBJECT,Boolean.class);
        basicTypeMap.put(Constant.BOOLEAN, Boolean.class);
        basicTypeMap.put(Constant.BOOLEAN_OBJECT, Byte.class);
        basicTypeMap.put(Constant.BYTE, Byte.class);

        collectionTypeMap.put(Constant.LIST, List.class);
        collectionTypeMap.put(Constant.MAP, List.class);
        collectionTypeMap.put(Constant.ARRAY, Array.class);
    }

    public static Class<?> getTypeClass(ValueObject valueObject) {
        if (TypeManager.basicContains(valueObject.getSimpleTypeName())) {
            return getBasicType(valueObject.getSimpleTypeName());

        } else if(TypeManager.collectionContains(valueObject.getSimpleTypeName())) {
            return getCollectionType(valueObject.getSimpleTypeName());

        } else if (TypeManager.customContains(valueObject.getTypeName())){
            return getCustomType(valueObject.getTypeName());
        } else {
            return null;
        }
    }

    private static void customObjectInit(String[] packageNames) {

        customTypeMap.putAll(ScannerFactory.scan(packageNames, FilterFlag.NONE));
    }

    public static boolean customContains(String typeName) {
        return customTypeMap.containsKey(typeName);
    }

    public static Class<?> getCustomType(String typeName) {
        return customTypeMap.get(typeName);
    }

    public static boolean basicContains(String typeName) {
        return basicTypeMap.containsKey(typeName);
    }

    public static Class<?> getBasicType(String typeName) {
        return basicTypeMap.get(typeName);
    }

    public static boolean collectionContains(String typeName) {
        return collectionTypeMap.containsKey(typeName);
    }

    public static Class<?> getCollectionType(String typeName) {
        return collectionTypeMap.get(typeName);
    }
}
